#include "stdafx.h"
#include "CText.h"


CText::CText(void)
{
}

CText::CText(CPoint pBegin, CPoint pEnd, COLORREF cPen)
{
	this->m_pBegin	= pBegin;
	this->m_pEnd	= pEnd;
	m_nAngle = NUM_OF_ANGLE;
	m_pCoordinates = new CPoint[NUM_OF_ANGLE];

	memset(&lf, 0, sizeof(LOGFONT));       // zero out structure
	lf.lfHeight = 20;                      // request a 12-pixel-height font
	lf.lfQuality = TRUE;
	_tcsncpy_s(lf.lfFaceName, LF_FACESIZE, _T("Time New Romen"), 7);
	sizeNor = 10;
	m_nShapeType = TEXT_T;
	m_szText = L"";

	this->m_cPenColor = cPen;
	m_brushColor.CreateSolidBrush(RGB(255, 255, 255));
	m_nPenStyle = PS_SOLID;
	m_nPenWidth = 2;
}

CText::CText (CPoint m_pBegin, CPoint m_pEnd, BASESHAPE__T m_nShapeType, CString m_szText)
{
	this->m_pBegin	= m_pBegin - CPoint (0, 10);
	this->m_pEnd	= m_pEnd;
	this->m_nShapeType = m_nShapeType;
	this->m_szText = m_szText;
	m_nAngle = NUM_OF_ANGLE;
	m_pCoordinates = new CPoint[NUM_OF_ANGLE];

	memset(&lf, 0, sizeof(LOGFONT));       // zero out structure
	lf.lfHeight = 20;                      // request a 12-pixel-height font
	lf.lfQuality = TRUE;
	_tcsncpy_s(lf.lfFaceName, LF_FACESIZE, _T("Time New Romen"), 7);
	sizeNor = 10;
	m_brushColor.CreateSolidBrush(RGB(255, 255, 255));
	m_nPenStyle = PS_SOLID;
	m_nPenWidth = 2;
}

void CText::Serialize ( CArchive &ar)
{
	if (ar.IsStoring() )
	{
		ar << m_pBegin << m_pEnd << m_clrBack << m_cPenColor << m_nShapeType << m_szText << m_color << m_nRotate;
	}
	else
	{
		int nShapeType;
		ar >> m_pBegin >> m_pEnd >> m_clrBack >> m_cPenColor >> nShapeType >> m_szText >> m_color >> m_nRotate;
		m_nShapeType = (BASESHAPE__T)nShapeType;
	}
}

BOOL CText::Draw(CDC *pDC)
{
	CFont SubFont, SupFont, NorFont;
	CString TempStr = m_szText;
	CRect *drawRect = new CRect(m_pBegin, m_pEnd);
	pDC->SaveDC();
	CSize sz;
	CRect outRect(0,0,0,0);
	CFont *oldFont;
	CPoint sub, sup, subofs, supofs;
	CString temp = TempStr;
	TCHAR c;
	LOGFONT lf1 = lf;
	int nsub, nsup;
	/*
	CPen cPen(m_nPenStyle, m_nPenWidth, m_cPenColor);
	pDC->SelectObject(&m_brushColor);
	CPen *pOldPen = pDC->SelectObject(&cPen);
	pDC->Polygon(m_pCoordinates, NUM_OF_ANGLE);
	pDC->SelectObject(pOldPen);
	pOldPen->DeleteObject();
	*/
	this->setCoordinate();
	pDC->SetTextAlign(TA_BOTTOM|TA_LEFT);

	VERIFY(NorFont.CreateFontIndirect(&lf1));

	sub.x = lf1.lfWidth/2;
	sup.x = lf1.lfWidth/2;
	sub.y = lf1.lfHeight/3*2;
	sup.y = lf1.lfHeight/3*2;

	subofs.x = lf1.lfWidth/2;
	supofs.x = lf1.lfWidth/2;
	subofs.y = lf1.lfHeight/3;
	supofs.y = lf1.lfHeight/3;

	lf1.lfWidth = sub.x;
	lf1.lfHeight = sub.y;
	VERIFY(SubFont.CreateFontIndirect(&lf1));

	lf1.lfWidth = sup.x;
	lf1.lfHeight = sup.y;
	VERIFY(SupFont.CreateFontIndirect(&lf1));

	do
	{
		int x=0;
		CString s = L"";
		c=' ';
		bool bFind=true;
		while (bFind)
		{
			x = TempStr.FindOneOf(L"^_");
			if (x == -1) 
			{
				bFind=false;
				x = TempStr.GetLength();
			}
			else if (x==TempStr.GetLength()-1) bFind=false;
			else if (TempStr[x] != TempStr[x+1]) 
			{
				bFind = false; 
				c=TempStr[x];
			}
			else x++;
			s=s+TempStr.Left(x);
			TempStr.Delete(0,min(x+1,TempStr.GetLength()));
		}
		sz = pDC->GetTextExtent(s);
		outRect.right += sz.cx;
		if (outRect.Height() < sz.cy) 
			outRect.top = outRect.bottom - sz.cy;
		
		switch (c) 
		{
		case '^':
			oldFont = pDC->SelectObject(&SupFont);
			sz = pDC->GetTextExtent(TempStr);
			outRect.right += sz.cx+supofs.x;
			TempStr.Delete(0);
			pDC->SelectObject(oldFont);
			break;
		case '_':
			oldFont = pDC->SelectObject(&SubFont);
			sz = pDC->GetTextExtent(TempStr);
			outRect.right += sz.cx + subofs.x;
			TempStr.Delete(0);
			pDC->SelectObject(oldFont);
			break;
		}
	}
	while (c != ' ');
	
	outRect.bottom += 2 * subofs.y;
	outRect.top -= 2 * subofs.x;
	CPoint Origin;

	Origin.y = drawRect->top;

	switch (DT_LEFT)
	{
	case DT_CENTER:
		Origin.x = drawRect->Width()/2 + drawRect->left;
		break;
	case DT_LEFT:
		Origin.x = drawRect->left;
		break;
	case DT_RIGHT:
		Origin.x = drawRect->right-outRect.Width();
	}

	CPoint pnt = Origin;

	TempStr = temp;
	do
	{
		int x=0;
		CString s = L"";
		c=' ';
		bool bFind=true;
		while (bFind)
		{
			x=TempStr.FindOneOf(L"^_");
			if (x==-1) 
			{
				bFind=false;
				x = TempStr.GetLength();
			}
			else if (x==TempStr.GetLength()-1) bFind=false;
			else if (TempStr[x]!=TempStr[x+1]) 
			{
				bFind=false; 
				c=TempStr[x];
			}
			else x++;
			s = s + TempStr.Left(x);
			TempStr.Delete(0,min(x+1,TempStr.GetLength()));
		}
		oldFont = pDC->SelectObject(&NorFont);
		sizeNor = pDC->GetTextExtent(m_szText);
		drawRect->right = drawRect->left + sizeNor.cx;
		drawRect->bottom = drawRect->top + sizeNor.cy / 3 * 5;
		m_pEnd.x = drawRect->right;
		m_pEnd.y = drawRect->bottom;
		pDC->ExtTextOut(pnt.x, min(drawRect->bottom, drawRect->top) + sizeNor.cy / 3 * 4, ETO_CLIPPED, drawRect, s, NULL);
		sz = pDC->GetTextExtent(s);
		pnt.x += sz.cx;
		
		nsup = pnt.y - supofs.y;
		nsub = pnt.y + subofs.y;
		if(nsup > nsub)
			swap(nsup, nsub);

		switch (c) 
		{
		case '^':
			oldFont = pDC->SelectObject(&SupFont);
			sizeSup = pDC->GetTextExtent(TempStr.Left(1));
			pDC->ExtTextOut(pnt.x, min(drawRect->bottom, drawRect->top) + sizeSup.cy * 1.15 , ETO_CLIPPED, drawRect, TempStr.Left(1), NULL);
			sz = pDC->GetTextExtent(TempStr.Left(1));
			pnt.x += sz.cx;
			TempStr.Delete(0);
			pDC->SelectObject(oldFont);
			break;
		case '_':
			oldFont = pDC->SelectObject(&SubFont);
			sizeSub = pDC->GetTextExtent(TempStr.Left(1));
			pDC->ExtTextOut(pnt.x, min(drawRect->bottom, drawRect->top) + sizeSub.cy / 4 + sizeNor.cy / 3 * 4,ETO_CLIPPED, drawRect,TempStr.Left(1),NULL);
			sz = pDC->GetTextExtent(TempStr.Left(1));
			pnt.x += sz.cx;
			TempStr.Delete(0);
			pDC->SelectObject(oldFont);
			break;
		}
	}
	while (c!=' ');
	

	return	FALSE;
}

void CText::setCoordinate()
{
	CRect cRect(m_pBegin, m_pEnd);
	m_pCoordinates[0]  = CPoint (cRect.left, cRect.top);
	m_pCoordinates[1]  = CPoint (cRect.left, cRect.bottom);
	m_pCoordinates[2]  = CPoint (cRect.right, cRect.bottom);
	m_pCoordinates[3]  = CPoint (cRect.right, cRect.top);
	m_pMax = m_pMin = m_pBegin;
	for(int i = 0; i < m_nAngle; i++)
	{
		m_pMin.x = min(m_pMin.x, m_pCoordinates[i].x);
		m_pMin.y = min(m_pMin.y, m_pCoordinates[i].y);
		m_pMax.x = max(m_pMax.x, m_pCoordinates[i].x);
		m_pMax.y = max(m_pMax.y, m_pCoordinates[i].y);

	}

}
CText::~CText(void)
{
}

